package main;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.ElementHandler;
import org.dom4j.ElementPath;
import org.dom4j.io.SAXReader;

public class FindTextGeneration {

	private String term_formatted_filename = "data/txt100";

	private String xml_filename = "data/xml.txt";

	private String output_filename = "data/found-text";

	protected Map topics = new HashMap();

	void gen() {
		try {
			readMyTermFormatted(term_formatted_filename);
			BufferedWriter bw = new BufferedWriter(new FileWriter(output_filename));
			Set set = topics.entrySet();
			List list = new ArrayList(set);
			Collections.sort(list, new comEntry());
			for (Iterator iter = list.iterator(); iter.hasNext();) {
				Topic topic = (Topic) ((Entry) iter.next()).getValue();
				processTopic(topic);
				write(topic, bw);
			}
			bw.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public class MyElementHandler implements ElementHandler {
		Passage psg;

		public MyElementHandler(Passage psg) {
			this.psg = psg;
		}

		public void onEnd(ElementPath path) {
			Element row = path.getCurrent();
			// if (i < psgs.size()) {
			// Passage psg = (Passage) psgs.get(i);
			// String pmid = row.elementText("PMID");
			// Element element = row.element("Article");
			// if (element != null)
			// element = element.element("Abstract");
			// String abstractText = element == null ? "" :
			// element.elementText("AbstractText");
			// if (pmid.equals(psg.getDocumentID())) {
			// psg.setTerms(abstractText);
			// i++;
			// while (i < psgs.size()) {
			// Passage next = (Passage) psgs.get(i);
			// if (pmid.equals(next.getDocumentID())) {
			// next.setTerms(abstractText);
			// i++;
			// } else {
			// break;
			// }
			// }
			// }
			// }
			String pmid = row.elementText("PMID");
			Element element = row.element("Article");
			if (element != null)
				element = element.element("Abstract");
			String abstractText = element == null ? "" : element.elementText("AbstractText");
			if (psg.getDocumentID().equals(pmid)) {
				psg.setTerms(abstractText);
				System.out.println(pmid);
			}
			row.detach();
		}

		public void onStart(ElementPath path) {
			// do nothing
		}

	}

	private void processTopic(Topic topic) throws DocumentException {
		Collections.sort(topic.getPassages(), new compPsgDocID());
		// Iterator<Passage> iter = topic.getPassages().iterator();
		// SAXParserFactory sf = SAXParserFactory.newInstance();
		// SAXParser sp = sf.newSAXParser();
		for (int i = 0; i < topic.getPassages().size(); i++) {
			SAXReader reader = new SAXReader();
			reader.addHandler("/MedlineCitationSet/MedlineCitation", new MyElementHandler((Passage) topic.getPassages()
					.get(i)));
			reader.read(new File(xml_filename));
		}
		Collections.sort(topic.getPassages(), new compPsgWeight());
	}

	private void write(Topic topic, BufferedWriter bw) throws IOException {
		for (Iterator iter = topic.getPassages().iterator(); iter.hasNext();) {
			Passage psg = (Passage) iter.next();
			StringBuffer sb = new StringBuffer();
			sb.append(topic.getId()).append("|||");
			sb.append(psg.getDocumentID()).append("|||");
			sb.append(psg.getTerms() == null ? "" : psg.getTerms());
			bw.write(sb.toString() + "\r\n");
		}
	}

	public static void main(String[] args) {
		if (args.length != 3) {
			System.out.println("Usage: java -cp .:dom4j-1.6.1.jar  FindTextGeneration txtTopic xmlName outputName");
			return;
		}
		FindTextGeneration ftg = new FindTextGeneration();
		ftg.term_formatted_filename = args[0];
		ftg.xml_filename = args[1];
		ftg.output_filename = args[2];
		ftg.gen();
	}

	/**
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	private void readMyTermFormatted(String filename) throws FileNotFoundException, IOException {
		BufferedReader fmt_file = new BufferedReader(new FileReader(filename));
		for (String tmp = fmt_file.readLine(); tmp != null; tmp = fmt_file.readLine()) {
			String[] tmpArr = tmp.split(" ");
			if (tmpArr.length == 6) {
				Topic topic = (Topic) topics.get(tmpArr[0]);
				if (topic == null) {
					topic = new Topic();
					topic.setId(tmpArr[0]);
					topics.put(topic.getId(), topic);
				}

				Passage psg = new Passage();
				psg.setDocumentID(tmpArr[2]);
				psg.setWeight(new BigDecimal(tmpArr[4]));
				psg.setOutString(tmp);
				topic.addPassage(psg);
			} else {
				System.err.println("file format error!");
			}
		}
		fmt_file.close();
	}

	protected class compPsgDocID implements Comparator {

		public int compare(Object o1, Object o2) {
			if (o1 == null && o2 == null) {
				return 0;
			}
			return ((Passage) o1).getDocumentID().compareTo(((Passage) o2).getDocumentID());
		}

	}

	protected class compPsgWeight implements Comparator {

		public int compare(Object o1, Object o2) {
			if (o1 == null && o2 == null) {
				return 0;
			}
			return ((Passage) o1).getWeight().compareTo(((Passage) o2).getWeight());
		}

	}

	protected class comEntry implements Comparator {

		public int compare(Object o1, Object o2) {
			if (o1 == null && o2 == null) {
				return 0;
			}
			Entry oe1 = (Entry) o1;
			Entry oe2 = (Entry) o2;
			return oe1.getKey().toString().compareTo(oe2.getKey().toString());
		}

	}

}
